package com.quwan.utils;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.*;
import com.quwan.common.service.oss.IObjectStorageStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.List;


/**
 *
 * @author lt
 * @version 1.0.0
 * @Date 2018/09/03 16:11
 */
public class OSSFileUtil implements IObjectStorageStrategy {
    private static final Logger logger = LoggerFactory.getLogger(OSSFileUtil.class);

    /**
     * accessKeyId
     */
    private String accessKeyId;
    /**
     * secretAccessKey
     */
    private String secretAccessKey;
    /**
     * endPoint
     */
    private String endPoint;
    /**
     * bucketName
     */
    private String bucketName;

    public OSSFileUtil(String accessKeyId, String secretAccessKey, String endPoint, String bucketName) {
        this.accessKeyId = accessKeyId;
        this.secretAccessKey = secretAccessKey;
        this.endPoint = endPoint;
        this.bucketName = bucketName;
    }

    /**
     * 创建ossClient
     */
    private OSS client;

    /**
     * 创建OSSClient实例
     */
    @Override
    public void createClient() {
        this.client = new OSSClientBuilder().build(endPoint, accessKeyId, secretAccessKey);
    }

    /**
     * 关闭OSSClient实例
     */
    @Override
    public void closeClient() {
        try {
            if (null != client) {
                client.shutdown();
            }
            client = null;
        } catch (Exception e) {
            logger.error("关闭ossClient发生异常：{}", e);
        }
    }

    /**
     * 根据key读取文件
     *
     * @param key
     * @return
     */
    @Override
    public byte[] getByteArrayByKey(String key) {
        byte[] data = null;
        try {
            OSSObject ossObject = client.getObject(this.bucketName, key);
            InputStream inputStream = ossObject.getObjectContent();
            // 读取文件内容
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            byte[] buffer = new byte[4096];
            int n;
            while (-1 != (n = inputStream.read(buffer))) {
                output.write(buffer, 0, n);
            }
            data = output.toByteArray();
        } catch (Exception e) {
            logger.error("获取二进制文件发生异常：{}", e);
        }
        return data;
    }

    /**
     * MultipartFile上传
     *
     * @param multipartFile
     * @param fileKey
     * @return
     */
    @Override
    public boolean storeFile(MultipartFile multipartFile, String fileKey) {
        try {
            InputStream inputStream = multipartFile.getInputStream();
            client.putObject(bucketName, fileKey, inputStream);
        } catch (Exception e) {
            logger.error("storeFile发生异常:", e);
            return false;
        }
        return true;
    }

    /**
     * File上传
     *
     * @param file
     * @param fileKey
     * @return
     */
    @Override
    public boolean storeLocalFile(File file, String fileKey) {
        try {
            InputStream inputStream = new FileInputStream(file);
            client.putObject(bucketName, fileKey, inputStream);
        } catch (Exception e) {
            logger.error("storeLocalFile发生异常:", e);
            return false;
        }
        return true;
    }

    /**
     * 流上传
     *
     * @param inputStream
     * @param fileKey
     * @return
     */
    @Override
    public boolean storeFileInputStream(InputStream inputStream, String fileKey) {
        try {
            client.putObject(bucketName, fileKey, inputStream);
        } catch (Exception e) {
            logger.error("storeFileInputStream发生异常:", e);
            return false;
        }
        return true;
    }

    /**
     * 清除已上传的文件
     *
     * @param fileKeyList
     * @return
     */
    @Override
    public boolean removeFileListByKeyList(List<String> fileKeyList) {
        if (fileKeyList == null) {
            return true;
        }
        boolean deleteStatus = true;
        try {
            DeleteObjectsRequest request = new DeleteObjectsRequest(bucketName).withKeys(fileKeyList);
            // 返回模式，默认详细模式；true简单模式，false详细模式
            request.setQuiet(false);
            DeleteObjectsResult deleteObjectsResult = client.deleteObjects(request);
            List<String> deletedObjects = deleteObjectsResult.getDeletedObjects();
            logger.info("已删除的图片数目:{}", deletedObjects.size());
        } catch (Exception e) {
            logger.error("removeFileListByKeyList异常:", e);
            deleteStatus = false;
        }
        return deleteStatus;
    }

    /**
     * 下载文件到本地
     *
     * @param fileName
     * @return
     */
    @Override
    public File getFile(String fileName, String localFile) throws IOException {
        File file = new File(localFile);
        // 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖，不存在则新建。
        client.getObject(new GetObjectRequest(bucketName, fileName), file);
        return file;
    }

    public InputStream getFileInputStream(String key) {
        // 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖，不存在则新建。
        try {
            OSSObject ossObject = client.getObject(new GetObjectRequest(bucketName, key));
            return ossObject.getObjectContent();
        } catch (Exception e) {
            logger.error("文件{}不存在", key);
        }
        return null;
    }

    public String[] listFileByKeyPrefix(String keyPrefix) {
        String[] strs = null;
        try {
            ObjectListing objectListing = client.listObjects(bucketName, keyPrefix);
            List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
            strs = new String[sums.size()];
            for (int i = 0; i <= sums.size(); i++) {
                strs[i] = sums.get(i).getKey();
            }
        } catch (Exception e) {
            logger.error("列举文件{}出现错误", keyPrefix, e);
        }
        return strs;
    }

    public static void main1(String[] args) throws Exception {

    }
}
